package com.thunder.reader.ui;

import java.io.FileNotFoundException;
import java.util.ArrayList;

import android.app.ListActivity;
import android.content.AsyncQueryHandler;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.net.Uri;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnCreateContextMenuListener;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.CursorAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

import com.thunder.reader.FeedSettings;
import com.thunder.reader.R;
import com.thunder.reader.provider.Feed;
import com.thunder.reader.transaction.Transaction;
import com.thunder.reader.transaction.TransactionService;
import com.thunder.reader.ui.ArticleListActivity.OnContentChangedListener;
public class FeedListActivity extends ListActivity {
    private static final String TAG = "FeedListActivity";
    private AsyncFeedQueryHandler mQueryHandler;
    private FeedListAdapter mListAdapter;
    private Uri mGroupUri;
    private static final int TOKEN_QUERY_ALL_FEED = 0;
    
    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        getWindow().requestFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
        final Intent intent =  getIntent();
        mGroupUri = intent.getData();
        final Uri groupUri = intent.getData();
        setTitle(getGroupName(groupUri));
        remmemberGroupId(groupUri);
        getListView().setOnCreateContextMenuListener(mContextMenu);
        mQueryHandler = new AsyncFeedQueryHandler(getContentResolver());
        mListAdapter = new FeedListAdapter(getApplication(), null);
        mListAdapter.addContentChangedListener(new OnContentChangedListener() {
            public void onContentChanged() {
                startAsyncQuery(groupUri);
            }
        });
        setListAdapter(mListAdapter);
        startAsyncQuery(groupUri);
    }

    private void remmemberGroupId(final Uri groupUri) {
        final SharedPreferences sp = getSharedPreferences(FeedSettings.getSharedPreferencesName(), Context.MODE_PRIVATE);
        final SharedPreferences.Editor editor = sp.edit();
        editor.putInt("group_id", Integer.valueOf(groupUri.getPathSegments().get(1)));
        editor.commit();
    }
    
    private String getGroupName(Uri groupUri) {
        final Cursor cursor = getContentResolver().query(groupUri, new String[]{Feed.Source.TITLE}, null, null, null);
        String groupName = null;
        if (cursor != null && cursor.moveToFirst()) {
            groupName = cursor.getString(0);
        }
        if (TextUtils.isEmpty(groupName)) {
            groupName = getString(R.string.label_group);
        }
        return groupName;
    }
    
    // IMPORTANT: ListActivity#onCreateContextMenu() won't get called. Fuck
    // you must set an context menu listener implementing View.OnCreateContextMenuListener to ListActiviy's ListView.
    // Fuck Android, what a sucking design.
//    @Override
//    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
//        menu.add(0, CONTEXT_MENU_EDIT_FEED, 0, R.string.edit_feed);
//        menu.add(0, CONTEXT_MENU_DELETE_FEED, 0, R.string.delete_feed);
//        menu.add(0, CONTEXT_MENU_UPDATE_FEED, 0, R.string.delete_feed);
//    }
    
    private OnCreateContextMenuListener mContextMenu = new OnCreateContextMenuListener() {
        public void onCreateContextMenu(ContextMenu menu, View v,
                ContextMenuInfo info) {
            final Uri sourceUri = ContentUris.withAppendedId(Feed.Source.CONTENT_URI, ((AdapterContextMenuInfo) info).id);
            final Cursor cursor = getContentResolver().query(sourceUri, new String[]{Feed.Source.TITLE}, 
                    null, null, null);
            if (cursor == null || !cursor.moveToFirst()) {
                return;
            }
            getMenuInflater().inflate(R.menu.feed_list_contextmenu, menu);
            menu.setHeaderTitle(cursor.getString(0));
            cursor.close();
        }
    };
    
    @Override
    public boolean onContextItemSelected(MenuItem item) {
        final AdapterView.AdapterContextMenuInfo menuInfo = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
        switch (item.getItemId()) {
        case R.id.feed_list_contextmenu_edit: {
            final Intent intent = new Intent(getApplication(), AddFeedActivity.class);
            intent.putExtra(AddFeedActivity.EXTRA_SOURCE_ID, menuInfo.id);
            startActivity(intent);
            break;
        }
        case R.id.feed_list_contextmenu_delete: {
            final Intent intent = new Intent(getApplication(), DeleteItemActivity.class);
            intent.putExtra(DeleteItemActivity.EXTRA_SOURCE_ID, menuInfo.id);
            startActivity(intent);
            break;
        }
        case R.id.feed_list_contextmenu_mark_as_read: {
            final ContentValues values = new ContentValues();
            values.put(Feed.Article.READ, 1);
            getContentResolver().update(Feed.Article.CONTENT_URI, values, 
                    Feed.Article.SOURCE_ID + "=?", new String[]{String.valueOf(menuInfo.id)});
            break;
        }
        case R.id.feed_list_contextmenu_mark_as_unread: {
            final ContentValues values = new ContentValues();
            values.put(Feed.Article.READ, 0);
            getContentResolver().update(Feed.Article.CONTENT_URI, values, 
                    Feed.Article.SOURCE_ID + "=?", new String[]{String.valueOf(menuInfo.id)});
            break;
        }
        case R.id.feed_list_contextmenu_update: {
            final Uri uri = ContentUris.withAppendedId(Feed.Source.CONTENT_URI, menuInfo.id);
            final Intent intent = new Intent(getApplication(), TransactionService.class);
            intent.putExtra(Transaction.EXTRA_TRANSACTION_TYPE, Transaction.TRANSACTION_TYPE_UPDATE_FEED);
            intent.setData(uri);
            startService(intent);
            break;
        }
        default:
            break;
        }
        return true;
    }
    
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.feed_list, menu);
        return true;
    }
    
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.feed_list_go_to_group: {
            startActivity(new Intent(getApplication(), GroupListActivity.class));
            finish();
            setTransitionAnimation();
            break;
        }
        case R.id.feed_list_add: {
            startActivity(new Intent(getApplication(), AddFeedActivity.class));
            break;
        }
        case R.id.feed_list_mark_all_as_read: {
            final ContentValues values = new ContentValues();
            values.put(Feed.Article.READ, 1);
            getContentResolver().update(Feed.Article.CONTENT_URI, values, 
                    Feed.Article.GROUP_ID + "=?", new String[]{mGroupUri.getPathSegments().get(1)});
            break;
        }
        case R.id.feed_list_mark_all_as_unread: {
            final ContentValues values = new ContentValues();
            values.put(Feed.Article.READ, 0);
            getContentResolver().update(Feed.Article.CONTENT_URI, values, 
                    Feed.Article.GROUP_ID + "=?", new String[]{mGroupUri.getPathSegments().get(1)});
            break;
        }
        case R.id.feed_list_update: {
            final Intent intent = new Intent(getApplication(), TransactionService.class);
            intent.putExtra(Transaction.EXTRA_TRANSACTION_TYPE, Transaction.TRANSACTION_TYPE_UPDATE_GROUP);
            intent.setData(mGroupUri);
            startService(intent);
            break;
        }
        default:
            break;
        }
        return true;
    }
    
    @Override
    public void onListItemClick(ListView listView, View view, int position, long id) {
        final Cursor cursor = (Cursor) listView.getItemAtPosition(position);
        final int sourceId = cursor.getInt(Feed.Source.ID_INDEX);
        final Uri sourceUri = ContentUris.withAppendedId(Feed.Source.CONTENT_URI, sourceId);
        Intent intent = new Intent(getApplication(), ArticleListActivity.class);
        intent.setData(sourceUri);
        startActivity(intent);
        overridePendingTransition(R.anim.default_come_enter, R.anim.default_come_exit);
    }
    
    @Override
    public void onBackPressed() {
	super.onBackPressed();
	setTransitionAnimation();
    }

    private void setTransitionAnimation() {
	overridePendingTransition(R.anim.default_leave_enter, R.anim.default_leave_exit);
    }
    
    private void startAsyncQuery(Uri groupUri) {
        getWindow().setFeatureInt(Window.FEATURE_INDETERMINATE_PROGRESS, Window.PROGRESS_INDETERMINATE_ON);
        mQueryHandler.startQuery(TOKEN_QUERY_ALL_FEED, null, Feed.Source.CONTENT_URI, Feed.Source.PROJECTION, 
                Feed.Source.GROUP_ID + "=?", new String[]{groupUri.getPathSegments().get(1)}, null);
    }
    
    private final class AsyncFeedQueryHandler extends AsyncQueryHandler {
        public AsyncFeedQueryHandler(ContentResolver cr) {
            super(cr);
        }
        
        @Override
        protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
            mListAdapter.changeCursor(cursor);
            getWindow().setFeatureInt(Window.FEATURE_INDETERMINATE_PROGRESS, Window.PROGRESS_INDETERMINATE_OFF);
        }
        
        @Override
        protected void onDeleteComplete(int token, Object cookie, int result) {
            
        }
        
        @Override
        protected void onUpdateComplete(int token, Object cookie, int result) {
            
        }
        
        @Override
        protected void onInsertComplete(int token, Object cookie, Uri uri) {
            
        }
    }

    private class FeedListAdapter extends CursorAdapter {
        private static final String TAG = "FeedListAdapter";
        private LayoutInflater mFactory;
        
        private ArrayList<OnContentChangedListener> mListenerList;
        
        public FeedListAdapter(Context context, Cursor c) {
            super(context, c, false);
            mFactory = LayoutInflater.from(context);
            mListenerList = new ArrayList<OnContentChangedListener>();
        }

        public void addContentChangedListener(OnContentChangedListener listener) {
            assert(mListenerList == null);
            mListenerList.add(listener);
        }
        
        @Override
        public void bindView(View view, Context context, Cursor cursor) {
            assert(view == null);
            TextView title = (TextView) view.findViewById(R.id.feed_list_item_title);
            TextView description = (TextView) view.findViewById(R.id.feed_list_item_description);
            TextView count = (TextView) view.findViewById(R.id.feed_list_item_count);
            title.setText(cursor.getString(Feed.Source.TITLE_INDEX));
            description.setText(cursor.getString(Feed.Source.DESCRIPTION_INDEX));
            final StringBuilder sb = new StringBuilder();
            sb.append(cursor.getString(Feed.Source.COUNT_UNREAD_INDEX));
            sb.append("/");
            sb.append(cursor.getString(Feed.Source.COUNT_INDEX));
            count.setText(sb.toString());
            if (cursor.getInt(Feed.Source.COUNT_UNREAD_INDEX) > 0) {
                count.setTextColor(Color.BLUE);
            } else {
                count.setTextColor(Color.BLACK);
            }
            ImageView thumbnail = (ImageView) view.findViewById(R.id.feed_list_item_thumbnail);
            Bitmap thumb = getThumbnail(cursor);
            if (thumb != null) {
                thumbnail.setImageBitmap(thumb);
            } else {
        	thumbnail.setImageResource(R.drawable.icon);
            }
        }

        @SuppressWarnings("unused")
	private String dumpFeedCursor(Cursor cursor) {
            final StringBuilder sb = new StringBuilder();
            sb.append("Title: " + cursor.getString(Feed.Source.TITLE_INDEX));
            sb.append("\ndescription " + cursor.getString(Feed.Source.DESCRIPTION_INDEX));
            sb.append("\nimage_url " + cursor.getString(Feed.Source.IMAGE_URL_INDEX));
            sb.append("\nimage_id " + cursor.getString(Feed.Source.IMAGE_ID_INDEX));
	    return sb.toString();
	}

	private Bitmap getThumbnail(Cursor cursor) {
            Bitmap bm = null;
            String imageId = cursor.getString(Feed.Source.IMAGE_ID_INDEX);
            if (TextUtils.isEmpty(imageId)) {
                return null;
            }
            final Uri uri = ContentUris.withAppendedId(Feed.Image.CONTENT_URI, Integer.valueOf(imageId));
            try {
                bm = BitmapFactory.decodeStream(getContentResolver().openInputStream(uri));
            } catch (FileNotFoundException e) {
            }
            return bm;
        }

        @Override
        public View newView(Context context, Cursor cursor, ViewGroup parent) {
            return mFactory.inflate(R.layout.feed_list_item, null);
        }
        
        @Override
        protected void onContentChanged() {
            for (OnContentChangedListener listener : mListenerList) {
                listener.onContentChanged();
            }
        }
    }
}